package isquirrel.recommender;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import isquirrel.beans.Interest;
import isquirrel.beans.Recommendation;
import isquirrel.beans.User;
import isquirrel.semantic.DBpedia;
import isquirrel.util.HibernateUtil;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import org.junit.Test;

public class StaticRecommenderTest {
	
	public User createUser1() {
		User u = new User();
		u.setFirstName("Andreas");
		u.setLastName("Matsikaris");
		
		HibernateUtil.getSession().saveOrUpdate(u);
		return u;
	}

	public Interest getInterest(String interest) {
		Set<String> subjects =( new DBpedia()).getSubjects(interest);

		if (subjects == null) {
			return null;
		}
		return new Interest(interest, subjects);
	}

	//Test
	public void testRecommendations() {
		HibernateUtil.useTestDB();
		HibernateUtil.beginTransaction();
		
		User u = createUser1();
		
		Interest interest = getInterest("Goldman Sachs");
		
		assertNotNull(interest);
		
		assertEquals(0,u.getUrls().size());
		
		StaticRecommender.insertRecommendations(u, interest);
		
		assertTrue(u.getUrls().size() > 0);
		
		StaticRecommender.deleteRecommendations(u, interest);
		
		assertEquals(0,u.getUrls().size());
		
		HibernateUtil.commit();
	}
	
	//Test
	public void testUpdateRecommendations() {
		HibernateUtil.useTestDB();
		
		//add test data
		HibernateUtil.beginTransaction();
		
		User u1 = createUser1();
		
		DBpedia dbPedia = new DBpedia();
		System.out.println("Getting Football subjects from dbPedia..");
		Interest interest = new Interest("Football",dbPedia.getSubjects("Football"));
		u1.addInterest(interest);
		StaticRecommender.updateRecommendations(u1);
		
		int footballRecommendations = u1.getUrls().size();
		System.out.println("# of football urls: "+footballRecommendations);
		
		u1.getInterests().remove(interest);
		StaticRecommender.updateRecommendations(u1);
		
		assertEquals(0,u1.getUrls().size());
		
		System.out.println("Getting Soccer subjects from dbPedia..");
		Interest interest2 = new Interest("Soccer",dbPedia.getSubjects("Soccer"));
		u1.addInterest(interest2);
		StaticRecommender.updateRecommendations(u1);
		
		int soccerRecommedations = u1.getUrls().size();
		System.out.println("# of soccer urls: "+soccerRecommedations);
		
		u1.addInterest(interest);
		StaticRecommender.updateRecommendations(u1);
		
		int bothInterests = u1.getUrls().size();
		System.out.println("# of football & soccer urls: "+bothInterests);
		
		assertTrue(bothInterests <= soccerRecommedations + footballRecommendations);
		
		u1.getInterests().remove(interest2); //removing soccer
		StaticRecommender.updateRecommendations(u1);
		
		System.out.println("# of football urls: "+ u1.getUrls().size());
		
		assertEquals(footballRecommendations, u1.getUrls().size());
		
		/*for(Url url : u1.getUrls()) {
			System.out.println(url.getAddress());
		}*/
		
		System.out.println("# of urls added: "+u1.getUrls().size());
		
		HibernateUtil.commit();
	}
	
	@Test
	public void testGetRecommendations() throws UnsupportedEncodingException {
		HibernateUtil.useTestDB();
		HibernateUtil.beginTransaction();
		
		User u1 = createUser1();
		StaticRecommender.insertRecommendations(u1, getInterest("Football"));
		
		HibernateUtil.commit();
		
		HibernateUtil.beginTransaction();
		
	List<Recommendation> recommendations = null;
	try {
		recommendations = StaticRecommender.getRecommendations(u1, false, 10, false);
	} catch (UnsupportedEncodingException e1) {
		e1.printStackTrace();
	}
		assertEquals(10,recommendations.size());
		
		for(Recommendation r : recommendations) {
			System.out.println(r.getPageTitle()+ "\t\t" + r.getUrl());
			//assertEquals(1, r.get.intValue());
		}
		List<Recommendation> new_recommendations = null;
		try {
			new_recommendations = StaticRecommender.getRecommendations(u1, false, 10, false);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		//check that the new recommendations are different than the previous ones
		System.out.println("\nNew Recommendations\n");
		for (Recommendation r_new : new_recommendations) {
			System.out.println(r_new.getPageTitle()+ "\t\t" + r_new.getUrl());
			assertFalse(recommendations.contains(r_new));
			//assertEquals(1,new_url.getRecommended().intValue());
		}		
		HibernateUtil.commit();
	}
	
	@Test
	public void getRandomNumberTest() {
		double sum = 0;
		double N = 10;
		for (int i = 0; i < N; i++) {
			int r = StaticRecommender.getRandomNumber(0, 100);
			System.out.println(r);
			sum += r;
		}
		System.out.println("Mean: "+sum/N);
	}
	
//	@Test
	public void addInterest()
	{
		HibernateUtil.beginTransaction();
		User u1 = createUser1();
		Interest interest = new Interest("computer science", new HashSet<String>());
		u1.addInterest(interest);
		HibernateUtil.commit();
	}
}

	